package engine;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import com.google.gson.*;

public class Messenger implements Runnable{
	List<String> actions;
//	private HttpServletResponse response;
	public boolean running = true;
	protected Gson gs;
	public Player human;
	public boolean isUpdating = false;
	public Messenger(){ //HttpServletResponse response
		this.actions = new ArrayList<String>();
//		this.response = response;
		this.gs = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
	}	
	
	public void callAction(Player player, String s){
		String json = gs.toJson(player);
		json = "player = " + json + "; " + s;
		System.out.println(json);
		synchronized (this.actions) {
			this.actions.add(json);
			this.actions.notify();
		}
		
	}
	public void callAction(String s){
		System.out.println(s);
		synchronized (this.actions) {
			this.actions.add(s);
			this.actions.notify();
		}
	}
	
	public void callAction(Player player, int bet, String s){
		String json = "player = " + gs.toJson(player) + "; " + "bet = \"" +  gs.toJson(bet) + "\"; " + s;
		System.out.println(json);
		synchronized (this.actions) {
			this.actions.add(json);
			this.actions.notify();
		}
	}
	
	public void callRestore(List<Player> players, List<Player> currentPlayers, List<Card> cCards, int[] playersBets, String s){
		String json;
		Gson gss = new Gson();
		json = "currentPlayers = " + gs.toJson(currentPlayers);
		json = json.replaceFirst("isHuman\\\"\\:true\\,\\\"hand\\\"\\:\\{\\\"cards\\\"\\:\\[\\{\\}\\,\\{\\}\\]\\}", "isHuman\":true,\"hand\":" + gss.toJson(human.hand));
		json += ", players = " + gs.toJson(players);
		json += ", cCards = " + gss.toJson(cCards);
		json += ", bets = " + gss.toJson(playersBets) + ", " + s;
		System.out.println(json);
		synchronized (this.actions) {
			if (this.actions.size() > 0){
				this.actions.set(0, json);
			}
			else {
				this.actions.add(json);
			}
			this.actions.notify();
		}
	}
	
	public void callAction(List<Player> players, boolean showHand, String s){
		String json;
		Gson gss = new Gson();
		if (showHand){
			json = "players = " + gs.toJson(players);
			for (int i = 0; i < players.size(); i++) {
				json = json.replaceFirst("\\[\\{\\}\\,\\{\\}]", gss.toJson(players.get(i).hand.cards));
			}
			
		}else{
			json = "players = " + gs.toJson(players);
			json = json.replaceFirst("isHuman\\\"\\:true\\,\\\"hand\\\"\\:\\{\\\"cards\\\"\\:\\[\\{\\}\\,\\{\\}\\]\\}", "isHuman\":true,\"hand\":" + gss.toJson(human.hand));
		}
		json += ", " + s;
		System.out.println(json);
		synchronized (this.actions) {
			this.actions.add(json);
			this.actions.notify();
		}
	}
	
	public void callAction(List<Card> cards, String s){
		Gson gss = new Gson();
		String json = "cCards = " + gss.toJson(cards) + ", " + s;
		System.out.println(json);
		synchronized (this.actions) {
			this.actions.add(json);
			this.actions.notify();
		}
	}
	
	@Override
	public void run() {
		while (running){
			if (this.actions.size() == 0){
				synchronized (this.actions) {
					try {
						this.actions.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
			if (!this.isUpdating){
				try {
					synchronized(this){
						wait();
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
//			try {
//				if (this.response == null){
//					try {
//						synchronized(this){
//							wait();
//						}
//					} catch (InterruptedException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//				}
//				PrintWriter pw = this.response.getWriter();
//				pw.println(this.actions.get(0));
//				pw.flush();
//				this.actions.remove(0);
//				this.response = null;
//				System.out.println(this.actions.size());
//			} catch (IOException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}

		}

	}
	public void stop() {
        running = false;
    }
	
//	public synchronized void setResponse(HttpServletResponse response){
//        this.response = response;
//        notify();
//    }
	
	public synchronized void getUpdate(HttpServletResponse response){
		if (this.actions.size() > 0){
			synchronized (this.actions) {
				PrintWriter pw = null;
				try {
					pw = response.getWriter();
					pw.println(this.actions.get(0));
					this.actions.remove(0);
					pw.flush();
					pw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		else {
			try {
				PrintWriter pw = response.getWriter();
				pw.println("console.log(\"nothing to update\")");
				pw.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.isUpdating = false;
	}
}
